import { Controller, Post, Body, BadRequestException } from '@nestjs/common';
import { TokenDto } from 'src/dto/token.dto';
import { CredentialsDto } from 'src/dto/credentials.dto';
import { StaffsService } from '../staffs/staffs.service';
import { PasswordService } from 'src/common/password/password.service';
import { JwtService } from '@nestjs/jwt';
import { JwtPayload } from './jwt.payload';
import { TokensService } from './tokens.service';
import { Identity } from 'src/schemas/staff/staff.interface';
import { ErrCode } from './code2session.interface';
import { CreateWeChatTokenDto } from 'src/dto/create-wechat-token.dto';
import { UsersService } from '../users/users.service';

@Controller('tokens')
export class TokensController {
  constructor(
    private readonly staffsService: StaffsService,
    private readonly passwordService: PasswordService,
    private readonly jwtService: JwtService,
    private readonly tokensService: TokensService,
    private readonly userService: UsersService,
  ) {}

  /**
   * 获取微信小程序用户令牌
   * @param js_code 微信小程序登录时获取的 code
   */
  @Post('wechat')
  async createWeChatToken(@Body() createWeChatTokenDto: CreateWeChatTokenDto) {
    // eslint-disable-next-line @typescript-eslint/camelcase
    const { js_code, nickName } = createWeChatTokenDto;
    const code2Session = (await this.tokensService.code2Session(js_code)).data;

    const { openid, errcode } = code2Session;

    // 获取 code2Session 失败，异常处理
    switch (errcode) {
      case ErrCode.Busy:
        throw new BadRequestException('请开发者稍候再试', '系统繁忙');

      case ErrCode.Invalid:
        throw new BadRequestException('请使用有效的 code', 'code 无效');

      case ErrCode.ApiLimit:
        throw new BadRequestException('每个用户每分钟100次', '频率限制');

      case ErrCode.Used:
        throw new BadRequestException('请换一个 code', 'code 已被使用过');
    }

    const { _id } = await this.userService.findAndCreateByOpenid(
      openid,
      nickName,
    );

    // 签发令牌
    return {
      token: this.jwtService.sign({
        _id,
        identity: Identity.WeChat,
      } as JwtPayload),
    } as TokenDto;
  }

  /**
   * 创建员工令牌
   * @param credentialsDto 凭据
   */
  @Post()
  async createToken(@Body() credentialsDto: CredentialsDto) {
    const { account } = credentialsDto;
    // 验证账户是否存在
    const staff = await this.staffsService.findStaffByAccount(account);

    // 判断用户是否注册
    if (!staff) {
      throw new BadRequestException('请先添加员工', '员工不存在');
    }

    // 验证账号密码匹配
    if (
      !(await this.passwordService.compare(
        credentialsDto.password,
        staff.password,
      ))
    ) {
      throw new BadRequestException('请重新输入账号或密码', '账号或密码错误');
    }

    const { _id, identity } = staff;

    // 签发令牌
    return {
      token: this.jwtService.sign({
        _id,
        identity,
      } as JwtPayload),
    } as TokenDto;
  }
}
